#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
//#include <boost/asio.hpp>

#define SERVIP "127.0.0.1"
#define SERVPORT 9899
#define MAXDATASIZE 100    /*每次最大数据传输量 */

//下位机注册数据长度
const int REGISTER_LENGTH = 6; 

//下位机发送数据长度
const int STATUS_LENGTH = 24; 

//上位机发送给下位机控制数据长度
const int CONTROL_LENGTH = 14; 

//注册数据
struct register_info_t
{
	register_info_t()
	{
		type = 1;
		user_id = 99;
		passwd = 1234;
	}

	char* to_string(char* s, int size)
	{
		if(s)
		{
			snprintf(s, size, "%d\t%d\t%d",
				type,
				user_id,
				passwd);
		}

		return s;
	}
	
	//数据类型
	int type:16;

	//下位机编号
	int user_id:16;
	
	//温度
	int passwd:16; 
};

//测量数据及泵状态
struct rcv_info_t
{
	rcv_info_t()
	{
		type = 2;
		user_id = 99;
		temperature = 16000;
		ph = 800;
		dodo = 1000;
		orp = -500;
		rbak1 = 0;
		air = 1;
		water = 1;
		mud = 1;
		flow = 3;
		rbak2 = 0;
	}

	//数据类型
	int type:16;

	//下位机编号
	int user_id:16;
	
	//温度
	int temperature:16; 

	//PH
	int ph:16;

	//浊度
	int dodo:16;

	//ORP
	int orp:16;

	//备用，默认为0
	int rbak1:16;

	//风机
	int air:16;

	//污水
	int water:16;

	//污泥
	int mud:16;

	//回流
	int flow:16;

	//备用，默认为0
	int rbak2:16;
};

//上位机发送到下位机的控制信息
struct control_info_t
{
	control_info_t()
	{
		user_id = 0;
		flag = 0;
		air = 0;
		water = 0;
		mud = 0;
		flow = 0;
		rbak2 = 0;
	}

	char* to_string(char* s, int size)
	{
		if(s)
		{
			snprintf(s, size, "%d\t%d\t%d\t%d\t%d\t%d\t%d",
				user_id,
				flag,
				air,
				water,
				mud,
				flow,
				rbak2);
		}

		return s;
	}
	
	//下位机编号
	int user_id:16;

	//标记，0为无控制，1为控制
	int flag:16;

	//风机
	int air:16;

	//污水
	int water:16;

	//污泥
	int mud:16;

	//回流
	int flow:16;

	//备用，默认为0
	int rbak2:16;

};

int main(int argc, char* argv[])
{
	int sock_fd, recvbytes;
	char buf[MAXDATASIZE];
	struct hostent *host;
	struct sockaddr_in serv_addr;
	
	if(argc <= 2)
	{
		std::cout << "we need 2 argv" << std::endl;
		return false;
	}

	//初始化
	if((host=gethostbyname(argv[2])) == NULL) {
	    herror("gethostbyname出错！");
	    exit(1);
	}
	if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
	    perror("socket创建出错！");
	    exit(1);
	}
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_port=htons(SERVPORT);
	serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
	bzero(&(serv_addr.sin_zero),8);
	
	//连接服务器
	if(connect(sock_fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) {
	    perror("connect出错！");
	    exit(1);
	}
	
	rcv_info_t rcv_info;
	rcv_info.user_id = atoi(argv[1]);
	
	//注册
	register_info_t register_info;
	register_info.user_id = atoi(argv[1]);
	if(send(sock_fd, &register_info, REGISTER_LENGTH, 0) == -1) 
	{
			perror("send出错！");
	}
	
	//读取控制信息
	if((recvbytes = recv(sock_fd, buf, CONTROL_LENGTH, 0)) == -1) 
	{
		perror("recv出错！");
	}
	if(recvbytes != CONTROL_LENGTH)
	{
		perror("recv length不一致");
		return false;
	}
	control_info_t* control_info = reinterpret_cast<control_info_t*>(buf);
	char s[1024];
	std::cout << control_info->to_string(s, 1024) << std::endl;
	
	sleep(1);
	
	
	//发送测量数据和泵状态数据
	while(1)
	{
		//发送数据
		if(send(sock_fd, &rcv_info, STATUS_LENGTH, 0) == -1) 
		{
				perror("send出错！");
				return false;
		}
		
		//读取控制信息
		if((recvbytes = recv(sock_fd, buf, CONTROL_LENGTH, 0)) == -1) 
		{
			perror("recv出错！");
			return false;
		}
		if(recvbytes != CONTROL_LENGTH)
		{
			perror("recv length不一致");
			return false;
		}
		control_info_t* control_info = reinterpret_cast<control_info_t*>(buf);
		char s[1024];
		std::cout << control_info->to_string(s, 1024) << std::endl;
		sleep(2);
   }

	close(sock_fd);
}
